[React] よーし! いっちょReactやってみっか! #6 スタイル編
はじめに
CX事業本部の中安です。まいどです。
モバイルアプリエンジニアな自分がReact
を始めてみることにした
「よーし! いっちょReactやってみっか!」シリーズの続きです。
今回もよろしくお願いします。
前回は、プロジェクトのデフォルト構成を一旦作り直してindex.js
の簡単な実装をしてみました。
今回はスタイルを当てる方法などをまとめてみたいなぁと思います。
スタイル直接指定
HTML
でstyle
属性を直接書くように要素のスタイルを書くことができます。
あくまでJSX
なのでHTML
とは仕様が違うところがあります。
大きな違いとしてはJavaScript
オブジェクトを渡すことと、その中身はCSS
でおなじみのケバブケースではなくキャメルケースで渡すことです。
簡単に書いてみるとこんな感じです。
const Hello = (props) => { let style = { backgroundColor: "gray", color: "#FFF", margin: 10, padding: 10, }; return ( <h1 style={style}>Hello World!</h1> ) }
margin
やpadding
には数字を直接渡すことができます。
これは勝手に数値の場合はpx
として扱ってくれるようです。
使うキーによってデフォルトの単位が決められているようで、
他の単位を指定したい場合は直接文字列(たとえば"100%"
など)で書くことになるようです。
ではブラウザで確認してみましょう。
見事に見え方が変わりました。
ただし、このスタイルを直接書くという方法は、公式ドキュメントには
(中略) style 属性を要素のスタイリングの主要な手段として使うことは一般的に推奨されません。多くの場合、className を使って外部の CSS スタイルシートに定義された CSS クラスを参照するべきです。
と書かれていて、パフォーマンスの観点からしても推奨される手法ではないとのことです。 簡単なサンプルを作るなどではお手軽でいいと思いますが、実務的なプロダクトとなるとこの手法は避けるべきでしょうね。
クラス指定
従来のWEBアプリでもスタイル直接指定よりもクラスなどによるCSS
でのスタイル指定が一般的ですね。
React
でも同じようにクラス指定でのスタイル定義ができます。
ここもJSX
だとHTML
と少しだけ仕様が違うようなので注意が必要です。
index.css
CSS
ファイルを作って、そこに先程のスタイル定義を移動させてみましょう。
まず、コマンドでCSS
ファイルを作ります。
% touch src/index.css
中を開いて編集しましょう。
.Hello-H1 { background-color: gray; color: #FFF; margin: 10px; padding: 10px; }
あまりセンスのいい命名じゃないですが、クラス名はHello-H1
にしてみました。
これは純粋なCSS
なので、先程のキャメルケースからケバブケースに戻し、ダブルクォートで囲った箇所はそれを外し、数値には単位をつけます。もちろんセミコロンで仕切ってやる必要があります。
index.js
index.js
に戻って、先程スタイル指定をしていた箇所を削除します。
const Hello = (props) => { return ( <h1>Hello World!</h1> ) }
次に、作ったCSS
ファイルをインポートしてやる必要があります。
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import './index.css';
同じ階層に配置しているので書き方としてはこんな感じでインポートします。
最後にCSS
で定義したスタイルを反映させるのですが、「HTML
と少しだけ仕様が違う」と書いたように
class
という属性ではなくclassName
という属性でクラスを指定します。(class
がJavaScript
の予約語だからと思われます)
const Hello = (props) => { return ( <h1 className="Hello-H1">Hello World!</h1> ) }
これでブラウザを確認してみましょう。
スタイル直接指定した時と同じ表示になると思います。
Bootstrapを使ってみる
CSS
フレームワークのおなじみのものといえばBootstrap
ですねっ。
(え? Material-UI じゃないの? って声はひとまず置いておいて・・・またどこかでやりますから・・・)
React
でBootstrap
を導入するにはどうしたらいいのでしょうね。
React Bootstrap
React
用に最適化されたReact Bootstrap
というものがあるようです。
React Bootstrap
の特長としては
React
用に再構築されている- 従来の
Bootstrap
に含まれるjQuery
などの依存関係を取り払っている React
で使いやすいようにコンポーネント化されている
という感じらしいです。ちょっと使ってみたいですね。
導入
こういったライブラリを導入するのはこのシリーズで初めてなので、
ついでなのでnpm
を使ってライブラリを導入する方法も確認してみたいと思います。
プロジェクトルートディレクトリにて以下のコマンドを打ちます。
% npm install react-bootstrap bootstrap
すると、インストールが始まりpackage.json
ファイルが更新されたかと思います。
npm install
に取り入れたいライブラリ名をスペース区切りで羅列していくことで、必要なライブラリなどを簡単に取り込むことができるわけですね。
インポート
単純にページ全体にBootstrap
のスタイルを適用するためには、以下のようにインポートを書いてやる必要があります。
こういうindex.js
のような全体に影響するJavaScript
ファイルに1箇所だけ書くのがよいとのことです。
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; // import './index.css';
※先程のindex.css
のインポートは干渉してしまうので一旦コメントアウトしています。
これだけで見た目がパッと変わると思います。
HTMLに埋め込むパターン
スタイルだけを適用させるのならば、そもそものHTML
に書いてしまうという方法もあるようです。
public/index.html
のヘッダ部分に<link>
タグを使ってCDNリンクを埋め込む方法が紹介されています。
<!DOCTYPE html> <html lang="en"> <head> ...中略... <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous" /> ...中略... </head>
※バージョン指定は古くなる可能性が高いのでこちらで確認ください。
React Bootstrap のコンポーネントを使う
いずれかの手法でBootstrap
のスタイルを読み込んだ後に、
React Bootstrap
のコンポーネント化された部品を使ってUI要素をリッチにすることができます。
ためしにButton
を使ってみますね。インポートを追加します。
import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import Button from 'react-bootstrap/Button';
HTML埋め込みパターンであれば、3行目はなしでいいです。
レンダリングしているところをこんな感じに書き換えます。
let dom = document.getElementById('root'); ReactDOM.render( <div className="card"> <div className="card-body"> <Button variant="outline-primary">プライマリーボタン</Button> </div> </div>, dom);
ちょっと見栄えよくしたいってことでcard
とかで囲ってみましたが、書きたかったのは<Button>
のところです。
variant
という属性にどういうスタイルのボタン化を指定することができるようですね。
ブラウザを確認すると
お、Bootstrap
的なボタンが表示されました。
Bootstrap
を使ったことがある方ならおなじみですが、primary
の他にもsecondary
、success
、dark
などが指定できますし、
上のようにoutline-
をつけると枠線だけになります。
では、レンダリングされたUIはどのようになっているかをブラウザで確認してみると
<div id="root"> <div class="card"> <div class="card-body"> <button type="button" class="btn btn-outline-primary">プライマリーボタン</button> </div> </div> </div>
こういうHTML
構成にレンダリングされていました。
変更したいbtn-*
のところだけを書くことができるので良いですね!
今回はボタンだけを試しましたが、React Bootstrap
ではもっと沢山のコンポーネントが用意されています。
他のコンポーネントについてはこちらのリンク先の左ペインからお好みのものを探してください。
ちなみに先程の例でいうと、カードもコンポーネントとして用意されているので、下記のように書き換えることができますね。
import React from 'react'; import ReactDOM from 'react-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; import Button from 'react-bootstrap/Button'; import Card from 'react-bootstrap/Card'; let dom = document.getElementById('root'); ReactDOM.render( <Card> <Card.Body> <Button variant="outline-primary">プライマリーボタン</Button> </Card.Body> </Card>, dom);
インポートの書き方の補足
公式のインポートによる記載なのですが
You should import individual components like: react-bootstrap/Button rather than the entire library. Doing so pulls in only the specific components that you use, which can significantly reduce the amount of code you end up sending to the client.
ライブラリ全体ではなく「react-bootstrap/Button」のように部分的にインポートすべきです。指定の使用するコンポーネントのみを取り込むことで、最終的にクライアントに送信するコードの大幅な量の削減ができるようになります。
import Button from 'react-bootstrap/Button'; // or less ideally import { Button } from 'react-bootstrap';
と、2種類の方法が記載されていました。
1つめの方法はreact-bootstrap
のButton
コンポーネントだけがインポートされる書き方になり、
2つめの方法はreact-bootstrap
全体を取り込んだ上でButton
をインポートする流れに現時点ではなるそうです。
(将来的には変わる可能性があるとのこと)
ですので、今回は1つめの方法を採用しました。
最後に
ということで、今回はスタイルの当てかたを色々ためしてみました。
また、npm
コマンドを用いてReact Bootstrap
をインストールし、使ってみるところまでをやりました。
スタイルについては、仕様の違いはあれど純粋なHTML+CSS
のときと書き方や考え方は異ならないようですね。
React
を初めて触るWEBエンジニアの方でもあまり違和感は感じないのではないでしょうか。
次回は「状態管理・ステート」あたりを触っていきましょうか。
では、またー。